package com.wzf.greattruth.test.zookeeper.lock;

import java.io.File;

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.ZooKeeper;

import com.wzf.greattruth.zookeeper.lock.DistributedLock;
import com.wzf.greattruth.zookeeper.lock.DistributedWaitLock;
import com.wzf.greattruth.zookeeper.lock.DistributedWaitLock;
import com.wzf.greattruth.zookeeper.lock.watcher.DistributedWaitLockWatcher;

public class ZookeeperLockTester {
    private static String HOST = "localhost:2181";
    private static int SESSION_TIMEOUT = 1000 * 60 * 60;
    private static final String dir = File.separator + "zk" + File.separator + "lock";

    public static void main(String[] args) throws Exception {

        ZooKeeper zookeeper = new ZooKeeper(HOST, SESSION_TIMEOUT, null);
        
        ZookeeperLockTester tester = new ZookeeperLockTester();

//         tester.testLockAndUnlock(zookeeper);
//         tester.testLockAndNeverUnlock(zookeeper);
        tester.testSerialLock(zookeeper);
        ;
        // zookeeper.close();

    }

    /**
     * 测试lock、unlock
     * 
     * @param distributionLock
     * @throws Exception
     */
    private void testLockAndUnlock(ZooKeeper zookeeper) throws Exception {
        String parentDir = dir;
        String nodeKey = "t1";
        DistributedLock distributionLock = new DistributedLock(zookeeper);
        boolean lock = distributionLock.lock(parentDir, nodeKey);
        System.err.println("lock1 result=" + lock);

        boolean lock2 = distributionLock.lock(parentDir, nodeKey);
        System.err.println("lock2 result=" + lock2);

        boolean unlock = distributionLock.unlock(parentDir, nodeKey);
        System.err.println("unlock result=" + unlock);

        System.err.println();
    }


    private void testSerialLock(final ZooKeeper zookeeper) throws Exception {

        int times = 5;
        for (int i = 0; i < times; i++) {
            final int index = i;
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    DistributedWaitLockWatcher<String> serialLockWatcher = new DistributedWaitLockWatcher<String>() {
                        @Override
                        public void callbackWhenGainLock(WatchedEvent event, String obj) {
                            System.err.println("**********************" + obj + " do job!");
                            
                        }};
                    String name = "Thread" + index;
                    Thread.currentThread().setName(name);
                    serialLockWatcher.setT(name);
                    DistributedWaitLock serialLock = new DistributedWaitLock(zookeeper, dir, serialLockWatcher);
                    boolean lock = false;
                    try {
                        lock = serialLock.lock();
                        System.err.println(Thread.currentThread().getName() + "   lock=" + lock);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if( lock ){
                        System.err.println( name + " gain lock first!");
                    }
                    
                    
                    try {
                        Thread.currentThread().sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    try {
                        boolean unlock = serialLock.unlock();
                        System.err.println(Thread.currentThread().getName() + "   unlock=" + unlock);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
            t.start();
        }

        Thread.currentThread().join();
        System.err.println();
    }

}
